/*
 * Main.java
 *
 * Created on March 26, 2006, 6:00 PM
 */

/**
 *
 * @author  Sujal Bista
 */
import java.net.*;
import java.io.*;
import java.util.StringTokenizer;


public class Main extends javax.swing.JFrame 
{
    
    public tcpClient client;
    public codeTable CodeTable;     //judge A specific
                    
    /** Creates new form Main */
    public Main() {
        
        /*
        nanduData nd=new nanduData();
        
        for(int i=0;i<nd.totalNandu;i++)
        {
            for(int j=0;j<nd.nanduList[i].getTotalMovements();j++)
            {
                System.out.print(nd.nanduList[i].getCode(j)+" "+nd.nanduList[i].getPoint(j)+"\t");
            }
            System.out.println("");
        }
        nd.find("324B+1");
        */
        
        initComponents();
        
        globalData.initGlobalData();
        globalData.scoringSystem=2;

        //setup global objects
        //pointer to the objects used by threads
        globalData.CaptionInput=CaptionInput;
        globalData.BoxInput=BoxInput;
        globalData.ButtonInput1=ButtonInput1;
        globalData.ButtonInput2=ButtonInput2;
        globalData.ButtonInput3=ButtonInput3;
        globalData.ButtonInput4=ButtonInput4;
        globalData.TextArea=TextArea;
                
        CodeTable = new codeTable();    //judge A specific
        
        initClient();
        
        globalData.setScreen();
        
        //disable them
        globalData.CaptionInput.setEnabled(false);
        globalData.BoxInput.setEnabled(false);
        globalData.ButtonInput1.setEnabled(false);
        globalData.ButtonInput2.setEnabled(false);
        globalData.ButtonInput4.setEnabled(false);
        globalData.ButtonInput3.setEnabled(false);
        
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanel1 = new javax.swing.JPanel();
        CaptionInput = new javax.swing.JLabel();
        BoxInput = new javax.swing.JTextField();
        ButtonInput1 = new javax.swing.JButton();
        ButtonInput2 = new javax.swing.JButton();
        ButtonInput3 = new javax.swing.JButton();
        ButtonInput4 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        TextArea = new javax.swing.JTextArea();
        jMenuBar1 = new javax.swing.JMenuBar();
        Menu = new javax.swing.JMenu();
        ExitM = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new java.awt.GridBagLayout());

        jPanel1.setFont(new java.awt.Font("Times New Roman", 0, 24)); // NOI18N
        jPanel1.setMinimumSize(new java.awt.Dimension(800, 700));
        jPanel1.setPreferredSize(new java.awt.Dimension(800, 700));
        jPanel1.setRequestFocusEnabled(false);
        jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        CaptionInput.setFont(new java.awt.Font("Times New Roman", 0, 24)); // NOI18N
        CaptionInput.setText("CaptionInput");
        jPanel1.add(CaptionInput, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 550, 710, -1));

        BoxInput.setFont(new java.awt.Font("Times New Roman", 0, 24)); // NOI18N
        BoxInput.setText("BoxInput");
        BoxInput.setMinimumSize(new java.awt.Dimension(220, 20));
        BoxInput.setPreferredSize(new java.awt.Dimension(220, 20));
        BoxInput.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                BoxInputActionPerformed(evt);
            }
        });
        BoxInput.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                BoxInputKeyPressed(evt);
            }
        });
        jPanel1.add(BoxInput, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 580, 710, 40));

        ButtonInput1.setFont(new java.awt.Font("Times New Roman", 0, 18)); // NOI18N
        ButtonInput1.setText("ButtonInput1");
        ButtonInput1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonInput1ActionPerformed(evt);
            }
        });
        jPanel1.add(ButtonInput1, new org.netbeans.lib.awtextra.AbsoluteConstraints(110, 510, 270, -1));

        ButtonInput2.setFont(new java.awt.Font("Times New Roman", 0, 18)); // NOI18N
        ButtonInput2.setText("ButtonInput2");
        ButtonInput2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonInput2ActionPerformed(evt);
            }
        });
        jPanel1.add(ButtonInput2, new org.netbeans.lib.awtextra.AbsoluteConstraints(400, 510, 270, -1));

        ButtonInput3.setFont(new java.awt.Font("Times New Roman", 0, 18)); // NOI18N
        ButtonInput3.setText("ButtonInput3");
        ButtonInput3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonInput3ActionPerformed(evt);
            }
        });
        jPanel1.add(ButtonInput3, new org.netbeans.lib.awtextra.AbsoluteConstraints(110, 640, 270, -1));

        ButtonInput4.setFont(new java.awt.Font("Times New Roman", 0, 18)); // NOI18N
        ButtonInput4.setText("ButtonInput4");
        ButtonInput4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonInput4ActionPerformed(evt);
            }
        });
        jPanel1.add(ButtonInput4, new org.netbeans.lib.awtextra.AbsoluteConstraints(400, 640, 270, -1));

        TextArea.setEditable(false);
        TextArea.setFont(new java.awt.Font("Times New Roman", 0, 14)); // NOI18N
        TextArea.setWrapStyleWord(true);
        TextArea.setFocusable(false);
        TextArea.setMargin(new java.awt.Insets(20, 20, 20, 20));
        jScrollPane1.setViewportView(TextArea);

        jPanel1.add(jScrollPane1, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 800, 500));

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(1, 0, 2, 0);
        getContentPane().add(jPanel1, gridBagConstraints);

        Menu.setText("File");

        ExitM.setText("Exit");
        Menu.add(ExitM);

        jMenuBar1.add(Menu);

        setJMenuBar(jMenuBar1);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void BoxInputActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_BoxInputActionPerformed
// TODO add your handling code here:
    }//GEN-LAST:event_BoxInputActionPerformed

    private void ButtonInput1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonInput1ActionPerformed

        switch(globalData.judgeType)
        {
            case 1: //judge A   mistake
            {
                client.sendMessage("Mistake");
                globalData.numButtonPressed++;
                if(globalData.numButtonPressed==1)
                    ButtonInput2.setEnabled(true); // enable to erase the last mistake entered
                break;
            }
            case 2: //judge B
            {
                client.sendMessage("Mistake");
                globalData.numButtonPressed++;
                if(globalData.numButtonPressed==1)
                    ButtonInput2.setEnabled(true); // enable to erase the last mistake entered            
                break;
            }
            case 3: //judge C   Success
            {
                int totalMovementCount=globalData.currentAthlete.getMovementsCount();
                if(globalData.numButtonPressed<totalMovementCount) //getNanduCount())
                {
                    client.sendMessage("Success");
                    globalData.numButtonPressed++;
                    globalData.nanduResults.add(true);
                    if(globalData.numButtonPressed==1)
                        ButtonInput3.setEnabled(true); // enable to undo 
                    if(globalData.numButtonPressed==totalMovementCount)
                    {
                        ButtonInput1.setEnabled(false); // disable success
                        ButtonInput2.setEnabled(false); // disable fail
                    }
                }
                break;
            }
        }
        updateScreen();
    }//GEN-LAST:event_ButtonInput1ActionPerformed

    private void ButtonInput2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonInput2ActionPerformed
        
        switch(globalData.judgeType)
        {
            case 1: //judge A   cancel
            {
                if(globalData.numButtonPressed>0)
                {
                    client.sendMessage("Cancel");
                    globalData.numButtonPressed--;
                    if(globalData.numButtonPressed==0)// disable so you only cancel the last timestamp
                        ButtonInput2.setEnabled(false);
                }
                break;
            }
            case 2: //judge B
            {
                if(globalData.numButtonPressed>0)
                {
                    client.sendMessage("Cancel");
                    globalData.numButtonPressed--;
                    if(globalData.numButtonPressed==0)// disable so you only cancel the last timestamp
                        ButtonInput2.setEnabled(false);
                }
                break; 
            }
            case 3: //judge C Fail
            {
                int totalMovementCount=globalData.currentAthlete.getMovementsCount();
                if(globalData.numButtonPressed<totalMovementCount) //getNanduCount())
                {
                    client.sendMessage("Fail");
                    globalData.numButtonPressed++;
                    globalData.nanduResults.add(false);
                    if(globalData.numButtonPressed==1)
                        ButtonInput3.setEnabled(true); // enable to undo 
                    if(globalData.numButtonPressed==totalMovementCount)
                    {
                        ButtonInput1.setEnabled(false); // disable success
                        ButtonInput2.setEnabled(false); // disable fail
                    }
                }
                break;
            }
        }
        updateScreen();
    }//GEN-LAST:event_ButtonInput2ActionPerformed

    private void ButtonInput3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonInput3ActionPerformed

        switch(globalData.judgeType)
        {
            case 1: //judge A   submit
            {
                // Send the final deduction string to the Head Judge
                String codes = BoxInput.getText();
                int status = ValidCodes(codes, globalData.numButtonPressed);
                if (status == 0) 
                {
                    CaptionInput.setText("Successfully submitted codes");
                    client.sendMessage("Codes " + BoxInput.getText());
                    BoxInput.setEnabled(false);
                    ButtonInput3.setEnabled(false);
                    ButtonInput4.setEnabled(true);
                }
                else if (status == 1) {
                    CaptionInput.setText("You entered invalid code numbers.  Please correct them.");
                }
                else if (status == 2) {
                    CaptionInput.setText("You entered too few codes.  Please enter more.");
                }
                else { // status == 3
                    CaptionInput.setText("You entered too many codes.  Please delete some.");
                }
                updateScreen();
                break;
            }
            case 2: //judge B   submit
            {
                String str=BoxInput.getText();

                // if correct, disable ButtonInput1, disable input box, enable Undo
                if (ValidRange(str)) 
                {
                    client.sendMessage(str);
                    globalData.numButtonPressed++;

                    BoxInput.setEnabled(false);
                    ButtonInput3.setEnabled(false);
                    ButtonInput4.setEnabled(true);

                    TextArea.setText("Successfully submitted.");
                }
                else    // if incorrect, flash a message
                {
                    TextArea.setText("Please enter valid score range. " + getValidRangeString());
                }
                break;
            }
            case 3: //judge C undo
            {
                if(globalData.numButtonPressed>0)
                {
                    client.sendMessage("Undo");
                    globalData.nanduResults.remove(globalData.nanduResults.size()-1);
                    globalData.numButtonPressed--;
                    if(globalData.numButtonPressed==0)// disable so you only cancel the last timestamp
                        ButtonInput3.setEnabled(false);
                    ButtonInput1.setEnabled(true);  //enable success
                    ButtonInput2.setEnabled(true);  //enable fail
                }
                updateScreen();
                break;
            }
        }
        
    }//GEN-LAST:event_ButtonInput3ActionPerformed

    private void ButtonInput4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonInput4ActionPerformed

        switch(globalData.judgeType)
        {
            case 1: //judge A
            {
                CaptionInput.setText("Please re-enter codes:");
                BoxInput.setEnabled(true);
                ButtonInput3.setEnabled(true);
                ButtonInput4.setEnabled(false);
                break;
            }
            case 2: //judge B undo
            {
                BoxInput.setEnabled(true);
                ButtonInput3.setEnabled(true);
                ButtonInput4.setEnabled(false);
                TextArea.setText("Please re-enter score.");
                break;
            }
            case 3: //judge C
            {
            
                break;
            }
            
        }
        updateScreen();
    }//GEN-LAST:event_ButtonInput4ActionPerformed

    private void BoxInputKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_BoxInputKeyPressed

        if(evt.getKeyChar()=='\n')
             ButtonInput3ActionPerformed(null);
    }//GEN-LAST:event_BoxInputKeyPressed

    //updates screen based of input received
    public void updateScreen()
    {
        switch(globalData.judgeType)
        {
            case 1: //judge A
            {
                globalData.TextArea.setText(globalData.currentAthlete.getEvent()+"\n");
                globalData.TextArea.append(globalData.currentAthlete.getGroup()+"\n");
                globalData.TextArea.append(globalData.currentAthlete.getName()+"\n");
                for(int i=0;i<globalData.currentAthlete.getNanduCount();i++)
                {
                    String nanduCode=globalData.currentAthlete.getNandu(i);
                    nanduData.nandu nanduDesc=globalData.nanduList.find(nanduCode);
                    if(nanduDesc!=null)
                    {
                        globalData.TextArea.append(Integer.toString(i+1)+" : "+nanduDesc.description);
                        globalData.TextArea.append("\n");                        
                        for(int j=0;j<nanduDesc.getTotalMovements();j++)
                        {                    
                            globalData.TextArea.append(nanduDesc.getCode(j)+"\t");
                        }
                        globalData.TextArea.append("\n\n");
                    }
                }
                globalData.TextArea.append("\n");
                globalData.TextArea.append("Mistakes Count : "+Integer.toString(globalData.numButtonPressed));
                break;
            }
            case 2: //judge B undo
            {
                globalData.TextArea.setText(globalData.currentAthlete.getEvent()+"\n");
                globalData.TextArea.append(globalData.currentAthlete.getGroup()+"\n");
                globalData.TextArea.append(globalData.currentAthlete.getName()+"\n");
                for(int i=0;i<globalData.currentAthlete.getNanduCount();i++)
                {
                    String nanduCode=globalData.currentAthlete.getNandu(i);
                    nanduData.nandu nanduDesc=globalData.nanduList.find(nanduCode);
                    if(nanduDesc!=null)
                    {
                        globalData.TextArea.append(Integer.toString(i+1)+" : "+nanduDesc.description);
                        globalData.TextArea.append("\n");
                        
                        for(int j=0;j<nanduDesc.getTotalMovements();j++)
                        {                    
                            globalData.TextArea.append(nanduDesc.getCode(j)+"\t");
                        }
                        globalData.TextArea.append("\n\n");
                    }
                }
                globalData.TextArea.append("\n");
                //globalData.TextArea.append("Mistakes Count : "+Integer.toString(globalData.numButtonPressed));
                break;
            }
            case 3: //judge C
            {
                int index=0;
                //globalData.TextArea.setText(globalData.currentAthlete.getEvent()+"\n");
                //globalData.TextArea.append(globalData.currentAthlete.getGroup()+"\n");
                globalData.TextArea.setText(globalData.currentAthlete.getName()+"\n");
                for(int i=0;i<globalData.currentAthlete.getNanduCount();i++)
                {
                    String nanduCode=globalData.currentAthlete.getNandu(i);
                    nanduData.nandu nanduDesc=globalData.nanduList.find(nanduCode);
                    if(nanduDesc!=null)
                    {
                        globalData.TextArea.append(Integer.toString(i+1)+" : "+nanduDesc.description);
                        globalData.TextArea.append("\n");
                        
                        for(int j=0;j<nanduDesc.getTotalMovements();j++)
                            globalData.TextArea.append(nanduDesc.getCode(j)+"\t");

                        globalData.TextArea.append("\n");
                        for(int j=0;j<nanduDesc.getTotalMovements();j++)
                        {                    
                            if(index<globalData.nanduResults.size())
                            {
                                if(((Boolean)globalData.nanduResults.get(index))==true)
                                    globalData.TextArea.append("Pass\t");
                                else
                                    globalData.TextArea.append("Fail\t");
                                ++index;
                            }
                        }
                        globalData.TextArea.append("\n");
                    }
                }
            }
            
        }
    }
    
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Main().setVisible(true);
            }
        });
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField BoxInput;
    private javax.swing.JButton ButtonInput1;
    private javax.swing.JButton ButtonInput2;
    private javax.swing.JButton ButtonInput3;
    private javax.swing.JButton ButtonInput4;
    private javax.swing.JLabel CaptionInput;
    private javax.swing.JMenuItem ExitM;
    private javax.swing.JMenu Menu;
    private javax.swing.JTextArea TextArea;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    // End of variables declaration//GEN-END:variables
    
    public void initClient()
    {
        client=new tcpClient();
        client.start();
    }
    
    
//judge A specific
/////////////////////////////////////////////////////////////////////////////////    
    private boolean ValidCode(String code)
    {
        return true;
        // must be 2-digit
       // if (code.length() != 2) {
       //     return false;
       // }
        
        // must be all digits
       // if (!Character.isDigit(code.charAt(0)) || !Character.isDigit(code.charAt(1))) {
       //     return false;
       // }
        
        //String event = globalData.currentAthlete.getEvent().toUpperCase();
        //int code_int = Integer.parseInt(code);
        
        //return CodeTable.isValid(event, code_int);
    }
    
    private int ValidCodes(String codes, int number)
    {
        StringTokenizer tokens = new StringTokenizer(codes);
        int numCodes = 0;
        while (tokens.hasMoreTokens()) {
            String token = tokens.nextToken();
            if (!ValidCode(token)) {
                System.err.println("Invalid code: " + token + " for event " + globalData.currentAthlete.getEvent());
                return 1;
            }
            
            numCodes++;
            
            if (numCodes > number) {
                return 3; // too many codes
            }
        }
        
        if (numCodes < number) {
            return 2; // too few codes
        }
        
        return 0;
    }
    
//judge B specific    
////////////////////////////////////////////////////////////////////////////////    

    private boolean ValidRange(String scoreString)
    {
        double score;
        try
        {
            score = Double.parseDouble(scoreString);
        }catch(Exception e)
        {
            return false;
        }
         if(globalData.scoringSystem==0)    //Traditional system
            return(0.0<=score && score<=10.0);
        else if(globalData.scoringSystem==1)// Nandu AB compulsory
            return (0 <= score  && score <= 5);
        return (0 <= score  && score <= 3); //Nandu ABC
    }
    
    //returns the valid range
    private String getValidRangeString()
    {
        String range="Valid range : ";
        // 0 Traditional System
        if(globalData.scoringSystem==0)//Traditional system
            range=range+"[ 0.0 - 10.0]";
        else if(globalData.scoringSystem==1)// Nandu AB compulsory
            range=range+"[ 0.0 - 5.0]";
        else
             range=range+"[ 0.0 - 3.0]";//Nandu ABC
        return range;
    }
    
//judge C specific    
////////////////////////////////////////////////////////////////////////////////    
    
    
}
